package config

import (
	"fmt"
	"os"
	"path/filepath"

	"gopkg.in/yaml.v3"
)

var Config YamlConfig

type YamlConfig struct {
	App         AppConfig         `yaml:"app"`
	Server      ServerConfig      `yaml:"server"`
	Database    DatabaseConfig    `yaml:"database"`
	Redis       RedisConfig       `yaml:"redis"`
	Login       LoginConfig       `yaml:"login"`
	File        FileConfig        `yaml:"file"`
	Openobserve OpenobserveConfig `yaml:"openobserve"`
	Mail        MailConfig        `yaml:"mail"`
	Ocpp        OcppConfig        `yaml:"ocpp"`
}

type AppConfig struct {
	Name         string `yaml:"name"`
	Version      string `yaml:"version"`
	Introduction string `yaml:"introduction"`
}

type ServerConfig struct {
	ServerId uint16   `yaml:"serverId"`
	Port     string   `yaml:"port"`
	AppMode  string   `yaml:"appMode"`
	BaseUrl  string   `yaml:"baseUrl"`
	PubUrl   []string `yaml:"pubUrl"`
}

type DatabaseConfig struct {
	MaxIdleConn int         `yaml:"maxIdleConn"`
	MaxOpenConn int         `yaml:"maxOpenConn"`
	ShowSQL     bool        `yaml:"showSQL"`
	LogLevel    string      `yaml:"logLevel"`
	Pgsql       PgsqlConfig `yaml:"pgsql"`
}

type PgsqlConfig struct {
	Dns string `yaml:"dns"`
}

type RedisConfig struct {
	Url string `yaml:"url"`
	Pwd string `yaml:"pwd"`
	Db  int    `yaml:"db"`
}

type LoginConfig struct {
	CaptchaEnable bool        `yaml:"captchaEnable"`
	MaxRetryCount bool        `yaml:"addrEnable"`
	LockTime      int         `yaml:"lockTime"`
	Token         TokenConfig `yaml:"token"`
}
type TokenConfig struct {
	Salt   string `yaml:"salt"`
	Ttl    string `yaml:"ttl"`
	RefTtl string `yaml:"refTtl"`
}

type FileConfig struct {
	BaseUrl string      `yaml:"baseUrl"`
	Local   LocalConfig `yaml:"local"`
	Oss     OssConfig   `yaml:"oss"`
}
type OpenobserveConfig struct {
	BaseUrl string `yaml:"baseUrl"`
	User    string `yaml:"user"`
	Pwd     string `yaml:"pwd"`
	Index   string `yaml:"index"`
}
type LocalConfig struct {
	RootPath string `yaml:"rootPath"`
}
type OssConfig struct {
	Endpoint   string `yaml:"endpoint"`
	AccessKey  string `yaml:"accessKey"`
	SecretKey  string `yaml:"secretKey"`
	BucketName string `yaml:"bucketName"`
}

type MailConfig struct {
	Sender string `yaml:"sender"`
	Sign   string `yaml:"sign"`
	From   string `yaml:"from"`
	SecKey string `yaml:"secKey"`
	Server string `yaml:"server"`
	Smtp   string `yaml:"smtp"`
}

type OcppConfig struct {
	ListenPort       int    `yaml:"listenPort"`
	DefIdTag         string `yaml:"defIdTag"`
	AuthRegisterPile string `yaml:"authRegisterPile"`
	AuthRegisterCard string `yaml:"authRegisterCard"`
}

// 初始化配置文件，需最优先初始化
func init() {
	fmt.Println("Optional startup parameters, such as:\n - go run main.go dev\n - go run main.go uat\n - go run main.go prod\n default use uat")
	args := os.Args
	configFile := "setting-uat.yaml"
	if len(args) > 1 {
		if args[1] == "dev" {
			configFile = "setting-dev.yaml"
		} else if args[1] == "uat" {
			configFile = "setting-uat.yaml"
		} else if args[1] == "prod" {
			configFile = "setting-prod.yaml"
		}
	}
	stRootDir, _ := os.Getwd()
	fPath := filepath.Join(stRootDir, "resources", configFile)
	// fPath := stRootDir + string(filepath.Separator) + "resources" + string(filepath.Separator) + "setting.yaml"
	file, err := os.ReadFile(fPath)
	if err != nil {
		panic("初始化配置文件异常:" + err.Error())
	}

	err = yaml.Unmarshal(file, &Config)
	if err != nil {
		panic("初始化配置文件异常:" + err.Error())
	}
}

// PrintConfig 打印配置
// func PrintConfig() {
// 	fmt.Println("**************************************************")
// 	fmt.Println("*                        ")
// 	fmt.Println("*   Welcome to code-go   ")
// 	fmt.Printf("*   Name: %s\n", Config.App.Name)
// 	fmt.Printf("*   PubApi: %v\n", Config.Server.PubApi)
// 	fmt.Printf("*   Introduction: %s\n", Config.App.Introduction)
// 	fmt.Printf("*   Environment: %s\n", Config.Server.AppMode)
// 	fmt.Printf("*   Click url：http://localhost:%d\n", Config.Server.Port)
// 	fmt.Printf("*   Swagger url: http://localhost:%d/swagger/index.html\n", Config.Server.Port)
// 	fmt.Println("*                        ")
// 	fmt.Println("**************************************************")
// }
